<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>原生实现SPA路由</title>
</head>

<body>
  <div class="router_box">
    <a href="/home.rmb" class="router" replace="true">主页</a>
    <a href="/news" class="router">新闻</a>
    <a href="/team" class="router">团队</a>
    <a href="/about100" class="router">关于</a>
  </div>
  <div id="router-view"></div>

  <script>
    // 自定义实现路由
    function Router(params) {
      // 记录routes配置
      this.routes = params.routes || [];
      // 记录路由模式
      this.mode = params.mode || 'hash';

      // 初始化
      this.init = function () {
        // 绑定路由响应事件
        var that = this;
        document.querySelectorAll(".router").forEach((item, index) => {
          item.addEventListener("click", function (e) {
            // 阻止a标签的默认行为
            if (e && e.preventDefault) {
              e.preventDefault();
            } else {
              window.event.returnValue = false;
            }

            if (that.mode == 'hash') {
              // 判断是replace方法还是push方法
              if (this.getAttribute("replace")) {
                var i = window.location.href.indexOf('#')
                // 通过replace方法直接替换url
                window.location.replace(
                  window.location.href.slice(0, i >= 0 ? i : 0) + '#' + this.getAttribute("href")
                )
              } else {
                // 通过赋值追加
                window.location.hash = this.getAttribute("href");
              }
            } else {
              if (this.getAttribute("replace")) {
                window.history.replaceState({}, '', window.location.origin + this.getAttribute("href"))
              } else {
                window.history.pushState({}, '', window.location.origin + this.getAttribute("href"))
              }
              // 手动调用更新内容方法
              that.routerChange();
            }

          }, false);
        });
        // 监听路由改变
        if (this.mode == 'hash') {
          window.addEventListener("hashchange", () => {
            this.routerChange();
          });
        } else {
          window.addEventListener('popstate', e => {
            this.routerChange();
          })
        }
        // 第一次进入的时候更新视图
        this.routerChange();
      }

      // 路由改变监听事件
      this.routerChange = function () {
        if (this.mode == 'hash') {
          let nowHash = window.location.hash;
          let index = this.routes.findIndex((item, index) => {
            return nowHash == ('#' + item.path);
          });

          if (index >= 0) {
            // 查找到对应路由
            document.querySelector("#router-view").innerHTML = this.routes[index].component;
          } else {
            // 没找到对应路由，查找有没有*
            let defaultIndex = this.routes.findIndex((item, index) => {
              return item.path == '*';
            });
            // 查找到*，执行重定向
            if (defaultIndex >= 0) {
              const i = window.location.href.indexOf('#')
              window.location.replace(
                window.location.href.slice(0, i >= 0 ? i : 0) + '#' + this.routes[defaultIndex].redirect
              )
            }
          }
        } else {
          let path = window.location.href.replace(window.location.origin, '');
          let index = this.routes.findIndex((item, index) => {
            return path == item.path;
          });
          if (index >= 0) {
            // 查找到对应路由
            document.querySelector("#router-view").innerHTML = this.routes[index].component;
          } else {
            // 没找到对应路由，查找有没有*
            let defaultIndex = this.routes.findIndex((item, index) => {
              return item.path == '*';
            });
            // 查找到*，执行重定向
            if (defaultIndex >= 0) {
              window.history.replaceState({}, '', window.location.origin + this.routes[defaultIndex].redirect)
              this.routerChange();
            }
          }
        }
      }

      this.init();
    }
    new Router({
      mode: 'history',
      routes: [{
          path: '/home.rmb',
          component: '<h1>主页</h1><h4>新一代前端工程师：我们啥都会</h4>'
        },
        {
          path: '/news',
          component: '<h1>新闻</h1><h4>今天2018-11-5，上课还得穿工装</h4>'
        },
        {
          path: '/team',
          component: '<h1>团队</h1><h4>WEB前端工程师</h4>'
        },
        {
          path: '/about',
          component: '<h1>关于</h1><h4>一面而高薪就业</h4>'
        },
        {
          path: '*',
          redirect: '/home.rmb'
        }
      ]
    });
  </script>
</body>

</html>